package com.botarena.server.servlets.rpc;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.jdo.JDOObjectNotFoundException;

import com.botarena.client.battle.remote.BattleAccess;
import com.botarena.server.model.Battle;
import com.botarena.server.model.Bot;
import com.botarena.server.model.Contest;
import com.botarena.server.services.BattleService;
import com.botarena.server.services.BotService;
import com.botarena.server.services.ContestService;
import com.botarena.shared.BattleInfo;
import com.botarena.shared.BattlePreviewInfo;
import com.botarena.shared.BattleTurn;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * Currently MOCK. In final version, this class should only call some methods of
 * the actual top-level services.
 * 
 */
public class BattleAccessImpl extends RemoteServiceServlet implements
		BattleAccess {

	private static final long serialVersionUID = -3760654059430068745L;

	private static final BotService bs = new BotService();
	private static final ContestService cs = new ContestService();

	public List<BattleInfo> getLatestBattlesInfo(final String contestKey,
			final int count) {
		List<BattleInfo> ret = new ArrayList<BattleInfo>();

		List<Battle> battles = BattleService.getLatestBattles(KeyFactory
				.stringToKey(contestKey), count);
		if (battles == null)
			return ret;

		for (Battle battle : battles) {
			BattleInfo bi = createBattleInfo(battle);

			ret.add(bi);
		}

		return ret;
		/*
		 * return Arrays .asList(new BattleInfo("OIAWEJDWIOoiawiwuaiw",
		 * "Zdzisio", "Zdenek", 1, "Main", "9.05.2011 22:30"));
		 */
	}

	@Override
	public BattlePreviewInfo getBattleProcess(String battleKey) {

		List<BattleTurn> process = BattleService.getBattleProcess(battleKey);
		Battle battle = BattleService.getBattleByKey(battleKey);
		BattlePreviewInfo info = new BattlePreviewInfo(
				createBattleInfo(battle), process, battle.getJustification());

		return info;
		/*
		 * return new BattlePreviewInfo("OIAWEJDWIOoiawiwuaiw", "Zdzisio",
		 * "Zdenek", 1, "Main", "9.05.2011 22:30", new LinkedList<BattleTurn>(),
		 * "blab eh");
		 */
	}

	@Override
	public List<BattleInfo> getBattles(int count, String contestKey,
			String botKey) {

		List<BattleInfo> ret = new ArrayList<BattleInfo>();

		List<Battle> battles;
		if (botKey == null)
			battles = BattleService.getAllBattles(KeyFactory
					.stringToKey(contestKey));
		else{
			battles = BattleService.getBotBattles(KeyFactory
					.stringToKey(botKey));
			Collections.sort(battles, new Comparator<Battle>() {

				@Override
				public int compare(Battle battle1, Battle battle2) {
					return battle1.getTime().compareTo(battle2.getTime());
				}
				
			});
		}

		if (battles == null)
			return ret;

		int num = 0;
		for (Battle battle : battles) {
			if (num < count)
				ret.add(createBattleInfo(battle));
			else
				ret.add(createEmpty(battle));
			num++;
		}

		return ret;
	}

	@Override
	public List<BattleInfo> getBattlesPart(List<String> battleKeys) {

		List<BattleInfo> ret = new ArrayList<BattleInfo>();

		List<Battle> battles = BattleService.getBattlesByKey(battleKeys);
		if (battles == null)
			return ret;

		for (Battle battle : battles) {
			BattleInfo bi = createBattleInfo(battle);
			ret.add(bi);
		}

		return ret;
	}

	private BattleInfo createBattleInfo(Battle battle) {
		String name1 = getBotName(battle.getBot1());
		String name2 = getBotName(battle.getBot2());

		Contest contest = cs.getByKey(battle.getContest());

		String strDate = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss")
				.format(battle.getTime());

		BattleInfo bi = new BattleInfo(KeyFactory.keyToString(battle.getKey()),
				name1, name2, battle.getWinnerNum(), contest.getName(), strDate);
		return bi;
	}

	private BattleInfo createEmpty(Battle battle) {
		BattleInfo bi = new BattleInfo(KeyFactory.keyToString(battle.getKey()),
				null, null, 0, null, null);
		return bi;
	}

	private String getBotName(Key key) {
		try {
			Bot bot1 = bs.getByKey(key);
			return bot1.getName();
		} catch (JDOObjectNotFoundException e) {
			return "-not-found-";
		}
	}

}